package AmazingMaze;

import java.awt.Dimension;

public class Plate {
    private Plate up, down, left, right;
    private Character character;
    private int info = 0;
    public static final int U = 38, D = 40, L = 37, R = 39;
    private boolean uv = true, dv = true, lv = true, rv = true;
    private boolean uw, dw, lw, rw;

    public static Plate[][] generateClearMaze(int w, int h) {
        Plate[][] plates = new Plate[w][h];
        for (int i = 0; i < plates.length; i++) {
            for (int j = 0; j < plates[0].length; j++) {
                plates[i][j] = new Plate();
                if (i > 0) {
                    plates[i][j].set(Plate.L, plates[i - 1][j]);
                    plates[i][j].setWall(Plate.L, false);
                    plates[i - 1][j].set(Plate.R, plates[i][j]);
                    plates[i - 1][j].setWall(Plate.R, false);
                } else {
                    plates[i][j].setWall(Plate.L, true);
                }
                if (i < plates.length - 1) {
                    plates[i][j].set(Plate.R, plates[i + 1][j]);
                    plates[i][j].setWall(Plate.R, false);
                } else {
                    plates[i][j].setWall(Plate.R, true);
                }
                if (j > 0) {
                    plates[i][j].set(Plate.U, plates[i][j - 1]);
                    plates[i][j].setWall(Plate.U, false);
                    plates[i][j - 1].set(Plate.D, plates[i][j]);
                    plates[i][j - 1].setWall(Plate.D, false);
                } else {
                    plates[i][j].setWall(Plate.U, true);
                }
                if (j < plates[0].length - 1) {
                    plates[i][j].set(Plate.D, plates[i][j + 1]);
                    plates[i][j].setWall(Plate.D, false);
                } else {
                    plates[i][j].setWall(Plate.D, true);
                }
            }
        }
        for (int i = 0; i < plates.length; i++) {
            for (int j = 0; j < plates[0].length; j++) {
                plates[i][j].hide();
            }
        }
        return plates;
    }

    public Plate(Plate up, Plate down, Plate left, Plate right) {
        this.up = up;
        if (up != null) {
            up.set(D, this);
        } else {
            uw = true;
        }
        this.down = down;
        if (down != null) {
            down.set(U, this);
        } else {
            dw = true;
        }
        this.left = left;
        if (left != null) {
            left.set(R, this);
        } else {
            lw = true;
        }
        this.right = right;
        if (right != null) {
            right.set(L, this);
        } else {
            rw = true;
        }
        // uv=dv=lv=rv=false;
    }

    public Plate() {
        this.up = null;
        this.down = null;
        this.left = null;
        this.right = null;
        // uv=dv=lv=rv=false;
        uw = dw = lw = rw = true;
    }

    public void setInfo(int info) {
        this.info = info;
    }

    public int getInfo() {
        return info;
    }

    public Dimension findSemself(Plate[][] map) {
        for (int x = 0; x < map.length; x++) {
            for (int y = 0; y < map[0].length; y++) {
                if (map[x][y] == this) {
                    return new Dimension(x, y);
                }
            }
        }
        return null;
    }

    public Plate get(int dir) {
        switch (dir) {
        case U:
            return up;
        case D:
            return down;
        case L:
            return left;
        case R:
            return right;
        }
        return null;
    }

    public boolean isVisible(int dir) {
        switch (dir) {
        case U:
            return uv;
        case D:
            return dv;
        case L:
            return lv;
        case R:
            return rv;
        }
        return false;
    }

    public void setVisible(int dir, boolean b) {
        switch (dir) {
        case U:
            uv = b;
            break;
        case D:
            dv = b;
            break;
        case L:
            lv = b;
            break;
        case R:
            rv = b;
            break;
        }
    }

    public void hide() {
        uv = dv = lv = rv = false;
    }

    public void show() {
        uv = dv = lv = rv = true;
    }

    public void set(int dir, Plate p) {
        switch (dir) {
        case U:
            up = p;
            break;
        case D:
            down = p;
            break;
        case L:
            left = p;
            break;
        case R:
            right = p;
            break;
        }
    }

    public void setWall(int dir, boolean w) {
        switch (dir) {
        case U:
            uw = w;
            break;
        case D:
            dw = w;
            break;
        case L:
            lw = w;
            break;
        case R:
            rw = w;
            break;
        }
    }

    public void setWalls() {
        uw = dw = lw = rw = true;
        if (up != null) {
            up.setWall(D, true);
        }
        if (down != null) {
            down.setWall(U, true);
        }
        if (left != null) {
            left.setWall(R, true);
        }
        if (right != null) {
            right.setWall(L, true);
        }
    }

    public boolean isWall(int dir) {
        switch (dir) {
        case U:
            return uw;
        case D:
            return dw;
        case L:
            return lw;
        case R:
            return rw;
        }
        return true;
    }

    public int dirOf(Plate p) {
        if (p == up) {
            return U;
        }
        if (p == down) {
            return D;
        }
        if (p == left) {
            return L;
        }
        if (p == right) {
            return R;
        }
        return 0;
    }

    public boolean isCharHere() {
        return character != null;
    }

    public void setChar(Character ch) {
        this.character = ch;
        ch.setPlace(this);
    }

    public void CharOut() {
        this.character = null;
    }
}
